package com.pcbly.web.components.license;

import java.io.IOException;
import java.io.Reader;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;  
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.pcbly.web.components.license.io.LicenseReader;
import com.pcbly.web.components.license.validator.Validator;
 
public class LicenseManager {
	private static final DateFormat dateFormat = DateFormat
			.getDateTimeInstance(2, 3);
	private static final Log log = LogFactory.getLog(LicenseManager.class);
	private License license;
	private LicenseProvider provider;

	public LicenseManager() {

	}

	public void initialize(LicenseProvider provider, Reader reader)
			throws LicenseException, IOException {
		this.provider = provider;
		license = null;
		LicenseReader licenseReader = new LicenseReader();
		License l = licenseReader.read(reader);
		 List<LicenseException> exceptions = validate(provider, l);
		if (!exceptions.isEmpty()) {
			throw new LicenseInitializationException(
					"License Validation Failed", exceptions);
		} else {
			l.getLicenseData().setVersion(provider.getVersion());
			license = l;
			return;
		}
	}

	public static List<LicenseException> validate(LicenseProvider provider, License license) {
		List<LicenseException> exceptions = new ArrayList<LicenseException>();
		for (Iterator<Validator> it = provider.getValidators().iterator(); it
				.hasNext();) {
			Validator v = it.next();
			try {
				v.validate(license);
			} catch (LicenseException e) {
				log.error(e.getMessage(), e);
				exceptions.add(e);
			}
		}

		return exceptions;
	}

	public License getLicense() {
		return license;
	}

	public boolean isInitialized() {
		return license != null;
	} 

	public static Date getDateProperty(String property, License license) {
		Date d = null;
		String s =  license.getLicenseData().getProperties().get(property);
		if (s != null)
			try {
				d = dateFormat.parse(s);
			} catch (ParseException e) {
				log.error(e.getMessage(), e);
			}
		return d;
	}

	protected void setLicense(License license) {
		this.license = license;
	}

	protected LicenseProvider getProvider() {
		return provider;
	}

	protected void setProvider(LicenseProvider provider) {
		this.provider = provider;
	}

}
